import os
import sys
import cairo
from gi.repository import Gtk, GLib

sys.path.insert(0, os.path.expanduser('~') + '/lib/python')

import mylib.util as util
import mylib.hw.disk as Disk
import mylib.hw.cpu as Cpu
import mylib.hw.net as Net
import mylib.rect as rect

class Conf(object):
    HORIZONTAL = 1
    VERTICAL = 2
    SPEED = 1000
    X = 100
    Y = 100
    WIDTH = 100
    HEIGHT = 400
    HDD = []  # disk usage (read/write)
    CPU = []  # cpu usage (cpu load)
    NET = []  # net usage (read/write)
    DISKS = []  # disk space


class HardWareMonitor(Gtk.Window):

    def __init__(self):
        super(HardWareMonitor, self).__init__()

        self.load_config()
        self.data = {}
        self.draw_area = Gtk.DrawingArea()
        self.draw_area.connect("draw", self.on_draw)
        self.add(self.draw_area)
        self.move(100, 100)

        self.timer = True
        self.alpha = 1.0
        self.size = 1.0

        self.cores = Cpu.get_core_stat_list()
        for core in self.cores:
            self.data[core.name] = []

        GLib.timeout_add(Conf.SPEED, self.on_timer)

        self.set_title("MHM")
        self.resize(Conf.WIDTH, Conf.HEIGHT)
        self.show_all()
        # self.set_decorated(False)
        # self.set_titlebar(label)

    def load_config(self):
        Conf.WIDTH = 100
        Conf.HEIGHT = 400
        Conf.DISKS.append(Disk.ntDiskUsage('root', '/', 2, 1, 1))
        Conf.DISKS.append(Disk.ntDiskUsage('home', '/media/home', 2, 1, 1))
        Conf.DISKS.append(Disk.ntDiskUsage('data', '/media/04Data', 2, 1, 1))
        Conf.DISKS.append(Disk.ntDiskUsage('tera1', '/media/06Tera1', 2, 1, 1))
        Conf.DISKS.append(Disk.ntDiskUsage('tera2', '/media/07Tera2', 2, 1, 1))

    def on_timer(self):
        if not self.timer: return False

        temp_data = list(self.cores)
        self.cores = Cpu.get_core_stat_list()
        diff_data = Cpu.diff_core_stat_list(self.cores, temp_data)
        for ii in range(len(diff_data)):
            itm = diff_data[ii]
            cpu_usage = 100.0 - (itm.idle * 100.0 / (itm[1] + itm[2] + itm[3] + itm[4]))
            self.data[itm[0]].append(cpu_usage)

        for i in range(len(Conf.DISKS)):
            Conf.DISKS[i] = Disk.get_disk_space(Conf.DISKS[i])
            # print("%-12s%8s/%8s" % (disk.name, hsize(disk.free), hsize(disk.total)))
        # print(Conf.DISKS)

        nres = Net.get_net_io()
        for dev in list(nres.keys()):
            if dev.startswith('eth'):
                print(nres[dev])

        dres = Disk.diskstats_parse()

        for dev in list(dres.keys()):
            if dev.startswith('hd') or dev.startswith('sd'):
                print(dres[dev])

        self.draw_area.queue_draw()
        return True

    @staticmethod
    def draw_graph(cr, rc, data, text=None):
        while len(data) > rc.width: data.pop(0)
        cr.set_antialias(cairo.ANTIALIAS_NONE)
        cr.rectangle(rc.left, rc.top, rc.width, rc.height)
        cr.set_source_rgba(0, 0, 0, 1)
        cr.fill()
        cr.set_line_width(1.0)
        x = rc.left
        val = 0
        lg = cairo.LinearGradient(rc.left, rc.top, rc.left, rc.bottom)
        lg.add_color_stop_rgba(0.1, 1, 0, 0, 1)
        lg.add_color_stop_rgba(0.6, 1, 1, 0, 1)
        lg.add_color_stop_rgba(0.9, 0, 1, 0, 1)
        cr.set_source(lg)
        for d in data:
            y = d * rc.height / 100.0
            cr.move_to(x, rc.bottom)
            cr.line_to(x, rc.bottom - y)
            x += 1.0
            val = d
        cr.stroke()
        cr.stroke_preserve()
        cr.set_source_rgba(0, 1, 0, 1)
        cr.move_to(rc.left, rc.top + 10)
        cr.select_font_face("굴림")
        cr.set_font_size(12)
        cr.show_text(text + ' ' + ('%2.2f' % val))
        # cr.text_path(text + ' ' + str(val))
        # cr.clip()
        # cr.paint_with_alpha(self.alpha)

    @staticmethod
    def draw_bar(cr, rc, data, hv=Conf.HORIZONTAL):
        if hv == Conf.HORIZONTAL:
            lg = cairo.LinearGradient(rc.left, rc.top, rc.right, rc.top)
            lg.add_color_stop_rgba(0.1, 0, 1, 0, 1)
            lg.add_color_stop_rgba(0.6, 1, 1, 0, 1)
            lg.add_color_stop_rgba(0.9, 1, 0, 0, 1)
            cr.set_source(lg)
        else:
            lg = cairo.LinearGradient(rc.left, rc.top, rc.left, rc.bottom)
            lg.add_color_stop_rgba(0.1, 1, 0, 0, 1)
            lg.add_color_stop_rgba(0.6, 1, 1, 0, 1)
            lg.add_color_stop_rgba(0.9, 0, 1, 0, 1)
            cr.set_source(lg)
        cr.rectangle(rc.left, rc.top, rc.width - rc.width * data.free / data.total, rc.height)
        cr.fill()
        cr.move_to(rc.left, rc.top + 10)
        cr.select_font_face("굴림체")
        cr.set_font_size(11)
        cr.set_source_rgba(0, 0, 1, 0.9)
        cr.show_text(data.name + ' ' + util.hsize(data.free))

    @staticmethod
    def fill_rect(cr, rc):
        cr.rectangle(rc.left, rc.top, rc.width, rc.height)
        cr.fill()

    def on_draw(self, wid, cr):
        w, h = self.get_size()

        cr.set_source_rgba(0.75, 0.75, 0.75, 0.75)
        cr.paint()
        y = 0
        keys = sorted(list(self.data.keys()))
        for key in keys:
            self.draw_graph(cr, rect.Rect(0, y, w, 50), self.data[key], key)
            y += 52

        for disk in Conf.DISKS:
            self.draw_bar(cr, rect.Rect(0, y, w, 16), disk)
            y += 17


def main():
    app = HardWareMonitor()
    app.connect("delete-event", Gtk.main_quit)
    Gtk.main()


if __name__ == "__main__":
    main()